/*
*
* ████████╗░█████╗░███████╗██████╗░░█████╗░
* ╚══██╔══╝██╔══██╗██╔════╝██╔══██╗██╔══██╗
* ░░░██║░░░██║░░██║█████╗░░██████╦╝███████║
* ░░░██║░░░██║░░██║██╔══╝░░██╔══██╗██╔══██║
* ░░░██║░░░╚█████╔╝██║░░░░░██████╦╝██║░░██║
* ░░░╚═╝░░░░╚════╝░╚═╝░░░░░╚═════╝░╚═╝░░╚═╝
* 
*  :: 九方通逊-Henry ::   Copyright©2020 tofba.com  
* 
*/
package com.lmexpress.util;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64.Decoder;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.apache.commons.lang3.StringUtils;

import com.lmexpress.enums.AmericaState;

/**
 * <API对接工具方法>
 * 
 * @author Henry(fba02)
 * @version [版本号, 2020-10-22]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class ApiUtil {
	public final static String DATE_FORMAT = "yyyy/MM/dd";
	public final static String DATE_MONTH_FORMAT = "yyyy-MM";
	public final static String TIME_ZONE = "Asia/Shanghai";
	public final static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	/**
	 * Day
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-10-16]
	 * @see [类、类#方法、类#成员]
	 */
	public static String getCurrentDay() {
		// 获取时区
		TimeZone zone = TimeZone.getTimeZone(TIME_ZONE);
		// 设置时区,使得输出时间与现在所处地区时间相符
		TimeZone.setDefault(zone);
		SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
		return df.format(new Date());
	}

	/**
	 * month
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-10-16]
	 * @see [类、类#方法、类#成员]
	 */
	public static String getCurrentMonthOnly() {
		// 获取时区
		TimeZone zone = TimeZone.getTimeZone(TIME_ZONE);
		// 设置时区,使得输出时间与现在所处地区时间相符
		TimeZone.setDefault(zone);
		SimpleDateFormat df = new SimpleDateFormat(DATE_MONTH_FORMAT);
		return df.format(new Date());
	}

	/**
	 * 
	 * <当前时间>
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-10-22]
	 * @see [类、类#方法、类#成员]
	 */
	public static synchronized String getCurrentDateTime() {
		TimeZone zone = TimeZone.getTimeZone(TIME_ZONE);// 获取时区
		TimeZone.setDefault(zone);// 设置时区,使得输出时间与现在所处地区时间相符
		SimpleDateFormat df = new SimpleDateFormat(DATE_TIME_FORMAT);
		return df.format(new Date());
	}

	/**
	 * 
	 * <当前时区时间>
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-10-22]
	 * @see [类、类#方法、类#成员]
	 */
	public static String getChinaTimeZoneTime() {
		TimeZone zone = TimeZone.getTimeZone("Asia/Shanghai");// 获取时区
		TimeZone.setDefault(zone);// 设置时区,使得输出时间与现在所处地区时间相符
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+08:00'");
		return df.format(new Date());
	}

	/**
	 * <将对象转xml>
	 * 
	 * @param shipRequest
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020年6月13日]
	 * @see [类、类#方法、类#成员]
	 */
	public static <T> String jaxbObjectToXML(Object object, Class<T> clazz) {
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
			Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
			jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			StringWriter stringWriter = new StringWriter();
			jaxbMarshaller.marshal(object, stringWriter);
			String xml = stringWriter.toString();
			return xml;
		} catch (JAXBException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * <Base64转文件>
	 * 
	 * @param base64Code
	 * @param targetPath
	 * @author Henry(fba02)
	 * @version [版本号, 2020-10-19]
	 * @see [类、类#方法、类#成员]
	 */
	public static boolean decoderBase64File(String base64Code, String targetPath) {
		Decoder decoder = java.util.Base64.getDecoder();
		byte[] buffer = decoder.decode(base64Code.replaceAll("[\\s*\t\n\r]", ""));
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(targetPath);
			out.write(buffer);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * <州简称-全称>
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, May 26, 2020]
	 * @see [类、类#方法、类#成员]
	 */
	public static Map<String, String> getAllAmericaState() {
		Map<String, String> result = new HashMap<String, String>();
		for (AmericaState americaState : AmericaState.values()) {
			result.put(americaState.toString(), americaState.getState().toUpperCase());
		}
		return result;
	}

	/**
	 * <州全称-简称>
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, May 26, 2020]
	 * @see [类、类#方法、类#成员]
	 */
	public static Map<String, String> getAllAmericaState2() {
		Map<String, String> result = new HashMap<String, String>();
		for (AmericaState americaState : AmericaState.values()) {
			result.put(americaState.getState().toUpperCase(), americaState.toString());
		}
		return result;
	}

	/**
	 * <小数点后两位数四舍五入>
	 *
	 * @param price 要四舍五入的价格
	 * @return double 四舍五入后的值
	 */
	public static Double round(Double price) {
		if (null == price || price.isInfinite() || price.equals(Double.NaN)) {
			return null;
		}
		return new BigDecimal(price).setScale(2, RoundingMode.HALF_UP).doubleValue();
	}

	/**
	 * <小数点后四位数四舍五入>
	 *
	 * @param price 要四舍五入的价格
	 * @return double 四舍五入后的值
	 */
	public static Double round(Double price, int precision) {
		if (null == price || price.isInfinite() || price.equals(Double.NaN)) {
			return null;
		}
		return new BigDecimal(price).setScale(precision, RoundingMode.HALF_UP).doubleValue();
	}

	/**
	 * <从字符串中取出整数>
	 * 
	 * @param str
	 * @return
	 */
	public static String subNumFromStr(String str) {
		String s = "";
		if (StringUtils.isBlank(str)) {
			return s;
		}
		Pattern p = Pattern.compile("-?[1-9]\\d*|0");
		Matcher m = p.matcher(str);
		while (m.find()) {
			s = m.group();
		}
		return s;
	}

	/**
	 * <MD5加密>
	 * 
	 * @param plainText
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-10-22]
	 * @see [类、类#方法、类#成员]
	 */
	public static String Md5(String plainText) {
		String ss = "";
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes("UTF-8"));
			byte[] b = md.digest();
			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				int i = b[offset];
				if (i < 0) {
					i += 256;
				}
				if (i < 16) {
					buf.append("0");
				}
				buf.append(Integer.toHexString(i));
			}
			ss = buf.toString();
		} catch (Exception exception) {
		}
		return ss.toString();
	}

	/**
	 * 
	 * <地址分析.>
	 * 
	 * @param address
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-12-8]
	 * @see [类、类#方法、类#成员]
	 */
	public static List<Map<String, String>> addressResolution(String address) {
		List<Map<String, String>> table = new ArrayList<Map<String, String>>();
		String regex = "(?<province>[^省]+自治区|.*?省|.*?行政区|.*?市)(?<city>[^市]+自治州|.*?地区|.*?行政单位|.+盟|市辖区|.*?市|.*?县)(?<county>[^县]+县|.+区|.+市|.+旗|.+海域|.+岛)?(?<town>[^区]+区|.+镇)?(?<village>.*)";
		Matcher matcher = Pattern.compile(regex).matcher(address);
		String province = null, city = null, county = null, town = null, village = null;
		Map<String, String> row = null;
		while (matcher.find()) {
			row = new LinkedHashMap<String, String>();
			province = matcher.group("province");
			row.put("province", province == null ? "" : province.trim());
			city = matcher.group("city");
			row.put("city", city == null ? "" : city.trim());
			county = matcher.group("county");
			row.put("county", county == null ? "" : county.trim());
			town = matcher.group("town");
			row.put("town", town == null ? "" : town.trim());
			village = matcher.group("village");
			row.put("village", village == null ? "" : village.trim());
			table.add(row);
		}
		return table;
	}

	/**
	 * < 生成UUID(JDK自带，去掉中间的'-'字符)>
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-12-9]
	 * @see [类、类#方法、类#成员]
	 */
	public static String generateUUID() {
		String uuid = generateOriginnalUUID();
		uuid = uuid.replaceAll("-", "");
		return uuid;
	}

	/**
	 * <生成UUID(JDK自带，中间带有'-'分割符)>
	 * 
	 * @return
	 * @author Henry(fba02)
	 * @version [版本号, 2020-12-9]
	 * @see [类、类#方法、类#成员]
	 */
	public static String generateOriginnalUUID() {
		return UUID.randomUUID().toString();
	}
}